<template>
  <el-dialog v-model="dialogVisible" :title="parameter.title" width="680px" lock-scroll destroy-on-close draggable>
    <el-form ref="formRef" :model="parameter.dict" :rules="rules" label-width="100px" label-suffix=" :">
      <el-tabs v-model="parameter.dict.dictType" tab-position="left">
        <!-- 目录 -->
        <el-tab-pane :name="0" label="分类">
          <el-form-item label="分类名称" prop="name">
            <el-input v-model="parameter.dict.name" placeholder="请填写分类名称" clearable />
          </el-form-item>
          <el-form-item label="分类编码" prop="code">
            <el-input v-model="parameter.dict.code" placeholder="请填写分类编码" clearable />
          </el-form-item>
        </el-tab-pane>
        <!-- 按钮 -->
        <el-tab-pane :name="1" label="字典">
          <el-form-item label="字典分类" prop="typeId">
            <el-select v-model="parameter.dict.typeId">
              <el-option v-for="item in formInline.dictTypeOptions" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="字典标识" prop="label">
            <el-input v-model="parameter.dict.label" placeholder="请填写字典标识" clearable />
          </el-form-item>
          <el-form-item label="字典值" prop="value">
            <el-input v-model="parameter.dict.value" placeholder="请填写字典值" clearable />
          </el-form-item>
          <el-form-item label="备注说明" prop="remarks">
            <el-input v-model="parameter.dict.remarks" type="textarea" placeholder="请填写备注说明" clearable />
          </el-form-item>
          <el-form-item label="权重(排序)" prop="sort">
            <el-input-number v-model="parameter.dict.sort" :precision="0" :value-on-clear="0" :min="0" />
          </el-form-item>
        </el-tab-pane>
      </el-tabs>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import type { ResultData, SysDict } from "@/api/interface";
import type { FormInstance, FormItemProp, FormRules } from "element-plus";
import { ref, reactive, watch } from "vue";
import { getDictTypeApi } from "@/api/modules/system/dict";
import { ElMessage } from "element-plus";

defineOptions({
  name: "SystemDictEdit"
});

/** 系统菜单 */
interface EditProps {
  /** 标题 */
  title: string;
  /** 待编辑的菜单 */
  dict: Partial<SysDict.Form>;
  /** 获取表格数据的Api */
  getTableList?: (refreshData: number) => void;
  /** 提交表单的Api */
  submitApi?: (params: any) => Promise<ResultData<boolean>>;
}

/** 表单内联数据 */
interface FormInline {
  /** 字典分类选项 */
  dictTypeOptions: SysDict.TypeResult[];
}

/** 表单实例 */
const formRef = ref<FormInstance>();
/** dialog 状态 */
const dialogVisible = ref(false);
/** 表单验证规则 */
const rules = reactive<FormRules>({
  name: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
  code: [{ required: true, message: "请输入分类编码", trigger: "blur" }],
  typeId: [{ required: true, message: "请选择字典分类", trigger: "blur" }],
  label: [{ required: true, message: "请输入字典标识", trigger: "blur" }],
  value: [{ required: true, message: "请输入字典值", trigger: "blur" }]
});
/** 父组件传过来的参数 */
const parameter = ref<EditProps>({
  title: "",
  dict: {
    dictType: 0,
    sort: 0
  }
});
/** 表单在线数据 */
const formInline = reactive<FormInline>({
  dictTypeOptions: []
});

/**
 * 接收父组件参数
 *
 * @param params 父组件传过来的参数
 * @returns void
 */
const acceptParams = (params: EditProps) => {
  parameter.value = params;
  dialogVisible.value = true;
};

/**
 * 初始化表单数据
 *
 * 1. 重置表单
 * 2. 获取上级菜单选项
 * 3. 加载表单数据
 *
 * @returns void
 */
const initFormInline = () => {
  formRef.value?.resetFields();

  getDictTypeApi().then(({ data }) => {
    formInline.dictTypeOptions = data;
  });
};

/**
 * 提交页面上的数据
 *
 * 1. 校验表单
 * 2. 提交表单
 * 3. 提交结果处理
 * 4. 异常处理
 *
 * @returns void
 */
const handleSubmit = () => {
  const fields: FormItemProp[] = parameter.value.dict.dictType === 0 ? ["name", "code"] : ["label", "value", "typeId"];

  formRef.value
    // 1. 校验表单
    ?.validateField(fields)
    // 2. 提交表单
    .then(() => {
      return parameter.value.submitApi!(parameter.value.dict);
    })
    // 3. 提交结果处理
    .then(({ data }) => {
      if (data) {
        ElMessage.success({ message: `${parameter.value.title}成功！` });
        parameter.value.getTableList!(parameter.value.dict.dictType!);
        dialogVisible.value = false;
      } else {
        ElMessage.error({ message: `${parameter.value.title}失败！` });
      }
    })
    // 4. 异常处理
    .catch((error: Error) => {
      if (error.message) ElMessage.error({ message: `${parameter.value.title}异常：${error.message}` });
      else ElMessage.error({ message: "请检查表单数据是否填写完整！" });
    });
};

// 监听 dialogVisible 的变化
watch(dialogVisible, val => {
  if (val) {
    initFormInline();
  }
});

// 暴露给父组件的属性和方法
defineExpose({
  acceptParams
});
</script>
